package org.coody.framework.cson.engine.unserializer;

import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;

import org.coody.framework.cson.convert.ValueConvert;
import org.coody.framework.cson.engine.unserializer.iface.AbstractUnserializer;
import org.coody.framework.cson.entity.ObjectWrapper;
import org.coody.framework.cson.entity.TypeEntity;
import org.coody.framework.cson.exception.CsonFormatException;
import org.coody.framework.cson.util.FieldUtil;

public class CollectionUnserializer extends AbstractUnserializer {

	@SuppressWarnings("unchecked")
	@Override
	public <T> ObjectWrapper<T> doAdapter(String json, TypeEntity type, int offset) {
		OutputSymboler output = getOutputSymboler(json, offset);
		if (output == null) {
			throw new CsonFormatException("错误的Json格式");
		}

		StringBuilder sbBuilder = new StringBuilder();
		boolean inContent = false;

		boolean isString = true;

		char last = '0';

		int length = 0;

		Collection<Object> object = null;
		if (!Collection.class.isAssignableFrom(type.getCurrent())) {
			object = new LinkedList<Object>();
			type.setCurrent(LinkedList.class);
			type.setActuals(Arrays.asList(new TypeEntity(Object.class)));
		} else {
			object = type.newInstance();
		}

		ObjectWrapper<T> wrapper = new ObjectWrapper<T>();

		for (int i = offset + output.getLength(); i < json.length(); i++) {
			length++;
			wrapper.setLength(i);
			char chr = json.charAt(i);
			if (chr == '"') {
				if (last != '\\') {
					inContent = inContent ? false : true;
					continue;
				}
			}
			if (!inContent) {
				if (chr == '[' || chr == '{') {
					ObjectWrapper<T> childWrapper = unserializer(json, type.getActuals().get(0), i + 1);
					if (childWrapper != null) {
						object.add(childWrapper.getObject());
					}
					i += childWrapper.getLength();
					length += childWrapper.getLength();
					sbBuilder = null;
					continue;
				}
				// 出栈
				if (chr == output.getOutputSymbol()) {
					if (sbBuilder != null && sbBuilder.length() > 0) {
						// 完成解析
						object.add(FieldUtil.parseValue(ValueConvert.convert(sbBuilder.toString(), isString),
								type.getCurrent()));
						sbBuilder = null;
					}
					isString = false;
					break;
				}
				if (chr == ',') {
					if (sbBuilder != null && sbBuilder.length() > 0) {
						object.add(FieldUtil.parseValue(ValueConvert.convert(sbBuilder.toString(), isString),
								type.getCurrent()));
						sbBuilder = null;
					}
					isString = false;
					continue;
				}
				if (chr == ':') {
					sbBuilder = null;
					isString = false;
					continue;
				}
			}
			if (sbBuilder == null) {
				sbBuilder = new StringBuilder();
			}
			last = chr;
			if (!isString && chr == ' ') {
				continue;
			}
			// 读取内容
			sbBuilder.append(chr);
		}
		wrapper.setObject((T) object);
		wrapper.setLength(length);
		return wrapper;
	}

}
